import { _decorator, Component, instantiate, Node, Prefab, Vec2 } from 'cc';
import { Direction, MAP_HEIGHT, MAP_WIDTH, SIZE } from './snakeMgr';
const { ccclass, property } = _decorator;

@ccclass('snake')
export class snake extends Component {
    private dir = 0;
    private isHead: boolean = false;
    nextBody: snake = null;
    private pos: Vec2 = new Vec2(0, 0);
    private lastPos: Vec2 = new Vec2(0, 0);
    set Dir(_dir: Direction) {
        if(_dir === Direction.UP && this.dir === Direction.DOWN) return;
        if(_dir === Direction.DOWN && this.dir === Direction.UP) return;
        if(_dir === Direction.LEFT && this.dir === Direction.RIGHT) return;
        if(_dir === Direction.RIGHT && this.dir === Direction.LEFT) return;
        this.dir = _dir;
    }
    initSnake(pos:Vec2, dir:number, isHead: boolean = false) {
        this.pos = pos;
        this.node.setPosition(pos.x, pos.y);
        this.dir = dir;
        this.isHead = isHead;
        this.node.active = true;
    }
    updateSnake(pos?:Vec2): Vec2 {
        
        this.setHead();
        if (!this.isHead) {
            this.setPos(pos);
        }
        this.updateBody();
        return this.pos;
    }

    setHead(){
        if(!this.isHead)return;

        switch (this.dir) {
            case Direction.UP:
                this.setPos(new Vec2(this.pos.x, this.pos.y + SIZE));
                this.node.angle = 0;
                break;
            case Direction.RIGHT:
                this.setPos(new Vec2(this.pos.x + SIZE, this.pos.y));
                this.node.angle = -90;
                break;
            case Direction.DOWN:
                this.setPos(new Vec2(this.pos.x, this.pos.y - SIZE));
                this.node.angle = 180;
                break;
            case Direction.LEFT:
                this.setPos(new Vec2(this.pos.x - SIZE, this.pos.y));
                this.node.angle = 90;
                break;
        }
    }

    setPos(_pos: Vec2) {
        if(_pos.x<0) _pos.x = MAP_WIDTH*SIZE + _pos.x;
        if(_pos.x >= MAP_WIDTH * SIZE) _pos.x = SIZE/2;
        if(_pos.y<0) _pos.y = MAP_HEIGHT*SIZE + _pos.y;
        if(_pos.y >= MAP_HEIGHT * SIZE) _pos.y = SIZE/2;
        
        this.lastPos = this.pos;
        this.pos = _pos;
        this.node.setPosition(this.pos.x, this.pos.y);
        
    }

    createBody(prefab:Prefab,parentNode:Node) {
        if(this.nextBody) {
            this.nextBody.createBody(prefab, parentNode);
            return;
        }
        const body = instantiate(prefab);
        this.nextBody = body.getComponent(snake);
        body.setParent(parentNode);
        this.nextBody.initSnake(this.lastPos, this.dir);
        
    }

    updateBody() {
        if (this.nextBody) {
            this.nextBody.updateSnake(this.lastPos);
        }
    }
    checkBody(pos?:Vec2):boolean {
        if(this.isHead){
            return this.nextBody && this.nextBody.checkBody(this.pos);
        }else{
            if(pos.equals(this.pos)) return true;
            else return this.nextBody && this.nextBody.checkBody(pos);
        }
    }
    
}


